package org.marverse.scripting

import ScriptingUtil._

sealed abstract case class UncheckedTupleExpr(val components: Seq[(Symbol, _ <: UncheckedExpression)])
extends UncheckedExpression {
  
}

object UncheckedTupleExpr {
  def apply(components: Seq[(Symbol, _ <: UncheckedExpression)]): UncheckedTupleExpr =
    new UncheckedTupleExprImpl(components)
  def apply(): UncheckedTupleExpr = 
    new UncheckedTupleExprImpl(Seq.empty)
  def apply(n1: Symbol, e1: UncheckedExpression): UncheckedTupleExpr = 
    new UncheckedTupleExprImpl(Seq((n1, e1)))
  def apply(n1: Symbol, e1: UncheckedExpression, n2: Symbol, e2: UncheckedExpression): UncheckedTupleExpr = 
    new UncheckedTupleExprImpl(Seq((n1, e1), (n2, e2)))
  def apply(n1: Symbol, e1: UncheckedExpression, n2: Symbol, e2: UncheckedExpression, n3: Symbol, e3: UncheckedExpression): UncheckedTupleExpr = 
    new UncheckedTupleExprImpl(Seq((n1, e1), (n2, e2), (n3, e3)))
}

sealed abstract case class TupleExpr(val components: Seq[(Symbol, _ <: Expression)]) extends Expression {
  def expressionType(implicit ctx: MutableTypedMap[TypedKey, Any]): TupleType
  def evaluate(implicit ctx: MutableTypedMap[TypedKey, Any]): TupleValue
}

private class UncheckedTupleExprImpl(components: Seq[(Symbol, _ <: UncheckedExpression)]) 
extends UncheckedTupleExpr(components) {
  
  override def childUncheckedExpressions = components map { _._2 }
  override def checked(implicit ctx: MutableTypedMap[TypedKey, Any]) = 
    new TupleExprImpl(components map (x => (x._1, x._2.checked)))

}

private class TupleExprImpl(components: Seq[(Symbol, Expression)]) 
extends TupleExpr(components) {
  
  override def childExpressions = components map { _._2 }
  override def expressionType(implicit ctx: MutableTypedMap[TypedKey, Any]) = 
    TupleType(components map { x => UncheckedVariableExpr(x._1, x._2.expressionType).declaration })
  override def evaluate(implicit ctx: MutableTypedMap[TypedKey, Any]) = 
    TupleValue(components map (_._2.evaluate))
  
}
